#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <pthread.h>


#define USEC_SLEEP  100
#define NUM_THREAD  5
const char* uitoax(int i)
{
    static char kstr_itoa[128] = {0};
    snprintf(kstr_itoa, 128, "%d", i);

    return kstr_itoa;
}


pthread_key_t kthreaddata_key;
void free_threaddata(void* t)
{
    if(0 != t) {
        printf("free  %p\n", (void*)t);
        free((void*)t);
    }
}


const char* uitoa(int i)
{
    void* p = pthread_getspecific(kthreaddata_key);
    if(NULL == p) {
        p = malloc(1024);
        pthread_setspecific(kthreaddata_key, p);
        printf("alloc %p\n", p);
    }
    
    if(NULL != p) {
        snprintf((char*)p, 1024, "%d", i);
    }

    return p;
}


void* func(void* arg)
{
    int i = 0;
    char str[128];
    while(i<10e7/USEC_SLEEP) {
        snprintf(str, 128, "%d", i);
        if(0 != strcmp(str, uitoa(i))) {
            printf("i=%d, str=%s, uitoax=%s.\n", i, str, uitoa(i));

            exit(0);
        }

        i++;
        usleep(USEC_SLEEP);
    }

    return NULL;
}


int main()
{
    pthread_key_create(&kthreaddata_key, free_threaddata);
    pthread_t pth;

    int i;
    for(i=0; i<NUM_THREAD; i++) {
        pthread_create(&pth, NULL, func, NULL);
    }

    while(1) {
        sleep(1);
    }

    return 0;
}
